package com.pocketmenu.persistence;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;

import com.pocketmenu.business.Constants;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.location.Location;
import android.util.Log;

public class RestaurantDataSource {
	
		// Database fields	  
	  private SQLiteDatabase database;	  
	  private RestaurantDataSource h=this;
	  private SQLiteHelper dbHelper;
	  private String[] allColumns = 
		  { SQLiteHelper.COLUMN_ID,
			SQLiteHelper.COLUMN_RESTAURANT_NAME,
			SQLiteHelper.COLUMN_RESTAURANT_DESCRIPTION,			
			SQLiteHelper.COLUMN_RESTAURANT_PHONE,
			SQLiteHelper.COLUMN_RESTAURANT_ADDRESS,
			SQLiteHelper.COLUMN_RESTAURANT_SMS,
			SQLiteHelper.COLUMN_RESTAURANT_EMAIL,			
			SQLiteHelper.COLUMN_RESTAURANT_AVAILABILITY,
			SQLiteHelper.COLUMN_RESTAURANT_LATITUD,
			SQLiteHelper.COLUMN_RESTAURANT_LONGITUD,
			SQLiteHelper.COLUMN_RESTAURANT_DISTANCE};

	  private SoapPrimitive resultado;
	  private boolean waitingForThread = true;
	  private boolean success = true;
	  
	  public String[] getAllColumnsName()
	  {
		  return allColumns;
	  }
	  
	  public RestaurantDataSource(Context context) {
	    dbHelper = new SQLiteHelper(context);
	  }

	  public void open() throws SQLException {		  
	    database = dbHelper.getWritableDatabase();	    
	  }
	  public SQLiteHelper getDbHelper() throws SQLException {
		  return dbHelper;
	  }

	  public void close() {
	    dbHelper.close();
	  }

	  public Restaurant create(String name, String description, String phone, String address, String sms, String email, String availability, String latitude, String longitude) {
	    ContentValues values = new ContentValues();
	    values.put(SQLiteHelper.COLUMN_RESTAURANT_NAME, name);
	    values.put(SQLiteHelper.COLUMN_RESTAURANT_DESCRIPTION, description);
	    values.put(SQLiteHelper.COLUMN_RESTAURANT_PHONE, phone);
	    values.put(SQLiteHelper.COLUMN_RESTAURANT_ADDRESS, address);
	    values.put(SQLiteHelper.COLUMN_RESTAURANT_SMS, sms);
	    values.put(SQLiteHelper.COLUMN_RESTAURANT_EMAIL, email);	    
	    values.put(SQLiteHelper.COLUMN_RESTAURANT_AVAILABILITY, availability);
	    values.put(SQLiteHelper.COLUMN_RESTAURANT_LATITUD, latitude);
	    values.put(SQLiteHelper.COLUMN_RESTAURANT_LONGITUD, longitude);
	    values.put(SQLiteHelper.COLUMN_RESTAURANT_DISTANCE, -1);
	    
	    long insertId = database.insert(SQLiteHelper.TABLE_RESTAURANT, null,
	        values);
	    
	    Cursor cursor = database.query(SQLiteHelper.TABLE_RESTAURANT,
	        allColumns, SQLiteHelper.COLUMN_ID + " = " + insertId, null,
	        null, null, null);
	    cursor.moveToFirst();
	    Restaurant newTemp = cursorToObject(cursor);
	    cursor.close();
	    return newTemp;
	  }

	  public void delete(Restaurant toDelete) {
	    int id = toDelete.getId();
	    System.out.println("Restaurant deleted with id: " + id);
	    database.delete(SQLiteHelper.TABLE_RESTAURANT, SQLiteHelper.COLUMN_ID
	        + " = " + id, null);
	  }

	  public List<Restaurant> getAll() {
	    List<Restaurant> listTemp = new ArrayList<Restaurant>();

	    Cursor cursor = database.query(SQLiteHelper.TABLE_RESTAURANT,
	        allColumns, null, null, null, null, null);

	    cursor.moveToFirst();
	    while (!cursor.isAfterLast()) {
	      Restaurant temp = cursorToObject(cursor);
	      listTemp.add(temp);
	      cursor.moveToNext();
	    }
	    // Make sure to close the cursor
	    cursor.close();
	    return listTemp;
	  }
	  
	  public Cursor getAllAsCursor()
	  {
		  Cursor cursor = database.query(SQLiteHelper.TABLE_RESTAURANT,
			        allColumns, null, null, null, null, SQLiteHelper.COLUMN_RESTAURANT_DISTANCE + " asc");
		   return cursor;		  			
	  }

	  public Restaurant cursorToObject(Cursor cursor) {
	    Restaurant temp = new Restaurant();
	    temp.setId(cursor.getInt(0));
	    temp.setName(cursor.getString(1));
	    temp.setDescription(cursor.getString(2));
	    temp.setPhone(cursor.getString(3));
	    temp.setAddress(cursor.getString(4));
	    temp.setSms(cursor.getString(5));
	    temp.setEmail(cursor.getString(6));	    
	    temp.setAvailability(cursor.getString(7));
	    temp.setLatitude(cursor.getString(8));
	    temp.setLongitude(cursor.getString(9));
	    temp.setDistance(cursor.getInt(10));
	    return temp;
	  }
	  
	  public Restaurant getRestaurant(int id)
	  {		  
		  Cursor cursor = database.query(SQLiteHelper.TABLE_RESTAURANT, allColumns, SQLiteHelper.COLUMN_ID + " = " + id, null, null, null, null);
		  cursor.moveToFirst();
		  Restaurant restaurant = cursorToObject(cursor);
		  cursor.close();
		  return restaurant;
	  }
	  
	  public boolean loadFromWeb(){
		  Thread networkThread = new Thread() {
      	    @Override
      	    public void run() {
	      	      
	  	    	//request       	    
	      	    String metodo = "select";	
	      	    SoapObject request= new SoapObject(Constants.namespace, metodo);
	      	    request.addProperty("tabla", "Restaurant");
	
	      	    //modelo sobre
	      	    SoapSerializationEnvelope sobre= new SoapSerializationEnvelope(SoapEnvelope.VER11);
	      	    sobre.dotNet = true;
	
	      	    sobre.setOutputSoapObject(request);
	
	      	    //transporte
	      	    HttpTransportSE transporte= new HttpTransportSE(Constants.url,10000);	          
	      	    transporte.debug = true;           
	
	      	    //llamada
	      	    try {
	      	    	transporte.call(Constants.namespace+metodo, sobre);
		   			
		   			//resultado
		   			resultado = (SoapPrimitive) sobre.getResponse();	   					   			
			   		success = true;
			   		
		   			} catch (Exception e) {
	   					Log.i("App.err " + getClass().getSimpleName(), e.getMessage());
		   				e.printStackTrace();
		   				success = false;
		   			}
	      	    waitingForThread = false;
      	    }	      	      
  	    };
  	    networkThread.start();
  	    
  	    while(waitingForThread){	      	    	
  	    }
  	    
  	    if(success)
  	    	return loadDataToDatabase();
  	    else
  	    	return false;
	  }
	  
	  private boolean loadDataToDatabase()
	  {
		  try
		  {						
			String respuesta=resultado.toString();
			String[] restaurantesWeb = respuesta.split(";");
				
			database.execSQL("DROP TABLE IF EXISTS " + SQLiteHelper.TABLE_RESTAURANT);
			database.execSQL(SQLiteHelper.TABLE_CREATE_RESTAURANT);
			
			for(int i=0;i<restaurantesWeb.length;i++){
				String[] restauranteWebActual=restaurantesWeb[i].split("\\*");
				h.create(restauranteWebActual[1],restauranteWebActual[2], restauranteWebActual[3], restauranteWebActual[7]
						, restauranteWebActual[4], restauranteWebActual[5], restauranteWebActual[6], restauranteWebActual[8]
						, restauranteWebActual[9]);				
			}
			success = true;
			Log.i("App.log " + getClass().getSimpleName(), "Exito");
		  }
		  catch(Exception e)
		  {
			  Log.i("App.err " + getClass().getSimpleName(), e.getMessage());
			  e.printStackTrace();
			  success = false;
		  }
		  
		  return success;
	  }	  	  
	  
	  public void updateRestaurantsWithDistance(Location currentLocation)
	  {		
		  if(currentLocation != null)
		  {
			  Cursor cursor = getAllAsCursor();
			  
			  cursor.moveToFirst();
			  
			  int idRestaurant = 0;
			  ContentValues values = new ContentValues();
			  Location restaurantLocation = new Location("");
			  int distance = 0;
			  String whereClause;
			  		  
			  while(!cursor.isAfterLast())
			  {
				  idRestaurant = cursor.getInt(0);			  
				  
				  restaurantLocation.setLatitude(Double.parseDouble(cursor.getString(8)));
				  restaurantLocation.setLongitude(Double.parseDouble(cursor.getString(9)));
				  
				  distance = (int) currentLocation.distanceTo(restaurantLocation);			  
				  
				  values.put(SQLiteHelper.COLUMN_RESTAURANT_NAME, cursor.getString(1));
				  values.put(SQLiteHelper.COLUMN_RESTAURANT_DESCRIPTION, cursor.getString(2));
				  values.put(SQLiteHelper.COLUMN_RESTAURANT_PHONE, cursor.getString(3));
				  values.put(SQLiteHelper.COLUMN_RESTAURANT_ADDRESS, cursor.getString(4));
				  values.put(SQLiteHelper.COLUMN_RESTAURANT_SMS, cursor.getString(5));
				  values.put(SQLiteHelper.COLUMN_RESTAURANT_EMAIL, cursor.getString(6));	    
				  values.put(SQLiteHelper.COLUMN_RESTAURANT_AVAILABILITY, cursor.getString(7));
				  values.put(SQLiteHelper.COLUMN_RESTAURANT_LATITUD, cursor.getString(8));
				  values.put(SQLiteHelper.COLUMN_RESTAURANT_LONGITUD, cursor.getString(9));
				  values.put(SQLiteHelper.COLUMN_RESTAURANT_DISTANCE, distance);
				  
				  whereClause = SQLiteHelper.COLUMN_ID + "=" + idRestaurant;
				  database.update(SQLiteHelper.TABLE_RESTAURANT, values, whereClause, null);
				  cursor.moveToNext();
			  }		  	
			  cursor.close();
		  }
	  }
}